iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Modern Web

了不起的 Svelte系列 第 24

第 24 天:Svelte 的互動百寶箱:Store(一)

  • 分享至 

  • xImage
  •  

第 24 天:Svelte 的互動百寶箱:Store(一)

第 24 天要講的事

  1. 簡介 Store
  2. 可複寫的 Store:writable Store

  關於 Svelte 的主題介紹不知不覺也已經超過 20 天了。對於 Svelte 的檔案架構的設計以及資料傳遞的方法都有不少概念了。今天就來讓我們探討在 Svelte 架構當中,最後一種,也是最自由的一種資料傳遞方式:Store。
  一般專案的設計方式是將資料由父元件 (parent component) 傳向子元件 (child component),除此之外,如果有需要,我們也學會使用 bind 資料綁定,讓子元件 (child component) 當中的資料可以反向影響父元件 (parent component) 當中的資料,也就是做到資料的雙向溝通。都已經做到這種地步了,還有可能有第三種資料傳遞的方式嗎?當然有,那就是橫向,也就是水平的資料傳遞。
  當專案變得較為複雜的時候,很可能縱向的資料傳遞無法適用所有的情境。有些時候,許多元件都需要取得相同的一份資料,或是許多元件都需要有權限能夠更新某一份資料。這時候硬是要把各個元件的做成階層結構,讓資料在其中做縱向傳遞,可能反而不合時宜。與其如此,如果讓互不隸屬的元件各自持有資料,並讓不同的資料能夠水平溝通,或許設計起來還較為簡單。
  那 Svelte 要怎麼做到這件事呢?答案是透過 Store。

簡介 Store

  Svelte 所提供的 Store,簡單來說就是一個可以儲存變數的地方。只要 Store 當中的變數一改變,任何跟這個變數相關聯的資料都能夠一併更新。咦,聽起來不就是一個一般的 Svelte 變數嗎?沒錯,這就像我們在第 07 天:Svelte 中的 Javascript:賦值當中介紹過,並且越來越熟悉的 Svelte 變數嗎?唯一的差別是,我們前面所介紹過的 Svelte 變數,都是寫在副檔名為 .svelte 的 Svelte 元件當中的變數。而今天介紹的 Store,則是一個可以用在副檔名為 .js,也就是一般的 Javascript 檔案的變數。
  如此一來,就不需要硬是將 Svelte 元件以階層架構堆疊起來去做資料傳遞,而可以直接利用載入 Javascript 檔案的方式來取出需要的變數。

可複寫的 Store:writable Store

  聽起來還是有點抽象陌生,讓我們實際來看一段程式碼吧:

/src/store.js
import { writable } from 'svelte/store';

export const stateStore = writable('');

  我們可以先到 Svelte 提供的 REPL (Read-Eval-Print-Loop,即線上編譯介面) 來試著使用看看 Store。首先新增一個新的檔案 store.js

  • 第一行:import { writable } from 'svelte/store';
      從 'svelte/store' 引入我們需要的 Store 類型 writable。顧名思義,這個 Store 當中儲存的變數,是可以複寫的。用 Javascript 的變數類型來做比喻的話,就是像可變變數 let

  • 第三行:export const stateStore = writable('');
      呼叫 writable,並使用空白字串 '' 當作參數。這個參數就是做為最一開始儲存在 writable Store 當中的變數。呼叫 writable 會傳回一個特殊的 Store 物件,我們把這個 Store 物件取名為 stateStore。而後我們就可以透過這個 Store 物件來取得儲存在 Store 當中變數的值,或是重新賦值。接著我們用 export 這個關鍵字讓其他檔案也可以直接使用 stateStore 這個 Store 物件。

/src/App.svelte
<script>
  import { onMount } from 'svelte';
  import { stateStore } from './store.js';
	
  let value;
	
  stateStore.subscribe((state) => value = state);
	
  onMount(() => {
    const interval = setInterval(() => stateStore.set(new Date()), 1000);
    return () => clearInterval(interval)
  })
</script>

<h1>Now is {value}!</h1>

  接著我們回到主要元件 App.svelte

  • 第三行:import { stateStore } from './store.js';
      在 Svelte 元件 App.svelte 當中可以直接引入 Javascript 檔案內的 Store 物件,也就是 stateStore

  • 第五行:let value;
      在 Svelte 元件當中宣告一個變數 value

  • 第七行:stateStore.subscribe((state) => value = state);
      呼叫 Store 物件 stateStore 的方法 subscribe,該方法會使用一個回呼函式 (callback function) 作為參數。只要 Store 物件內儲存的變數一發生改變,就會執行這個回呼函式。而這個回呼函式的參數就是代表 Store 物件當中所儲存的變數。所以這一段程式碼的意思很簡單,只要 stateStore 內儲存的變數一發生改變,就透過 (state) => value = state 將 Store 物件內儲存的變數的值,賦予給 Svelte 元件當中的變數 value。所以樣一來,Svelte 元件當中的 value,就跟 Store 物件當中的變數連動在一起了。

  • 第十行:const interval = setInterval(() => stateStore.set(new Date()), 1000);
      Store 物件除了 subscribe 之外,還有一個方法 set,利用這個方法可以直接設定 Store 物件內儲存的變數的值。所以這一行程式碼的意思也很簡單,就是利用 stateStore.set(new Date()),每個一秒,就重新將 Store 物件內儲存的變數更新為現在的時間。

  • 第十五行:<h1>Now is {value}!</h1>
      將 value 的值顯示在 HTML 的 <h1> 元素當中。因為前面已經將 valuestateStore 當中的變數連動在一起了,所以就會看到 value 一分一秒的向前邁進。

https://i.ibb.co/h7JXf0R/24.gif
圖一、在 Svelte 的 REPL 做一個時鐘

  那麼今天關於 Svelte Store 的介紹就先到這邊,明天再繼續讓我們透過專案的應用來更熟悉 Store 這個好用的工具吧!


上一篇
第 23 天:Svelte 資料綁定 `bind`(二)
下一篇
第 25 天:Svelte 的互動百寶箱:Store(二)
系列文
了不起的 Svelte30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言